<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style type="text/css">
      .container {
      }

      .container .cart {
        width: 300px;
        /*background-color: lightgreen;*/
        margin: auto;
      }

      .container .title {
        background-color: lightblue;
        height: 40px;
        line-height: 40px;
        text-align: center;
        /*color: #fff;*/
      }

      .container .total {
        background-color: #ffce46;
        height: 50px;
        line-height: 50px;
        text-align: right;
      }

      .container .total button {
        margin: 0 10px;
        background-color: #dc4c40;
        height: 35px;
        width: 80px;
        border: 0;
      }

      .container .total span {
        color: red;
        font-weight: bold;
      }

      .container .item {
        height: 55px;
        line-height: 55px;
        position: relative;
        border-top: 1px solid #add8e6;
      }

      .container .item img {
        width: 45px;
        height: 45px;
        margin: 5px;
      }

      .container .item .name {
        position: absolute;
        width: 90px;
        top: 0;
        left: 55px;
        font-size: 16px;
        height: 55px;
      }

      .container .item .change {
        width: 100px;
        position: absolute;
        top: 0;
        right: 50px;
      }

      .container .item .change a {
        font-size: 20px;
        width: 30px;
        text-decoration: none;
        background-color: lightgray;
        vertical-align: middle;
      }

      .container .item .change .num {
        width: 40px;
        height: 25px;
      }

      .container .item .del {
        position: absolute;
        top: 0;
        right: 0px;
        width: 40px;
        text-align: center;
        font-size: 40px;
        cursor: pointer;
        color: red;
      }

      .container .item .del:hover {
        background-color: orange;
      }
    </style>
  </head>

  <body>
    <div id="app">
      <div class="container">
        <cart></cart>
      </div>
    </div>

    <template id="cart">
      <div class="cart">
        <cart-header></cart-header>
        <!-- 
          @add-count="addCount"
          @sub-count="subCount"
         -->
        <cart-list :list="list" @del="del" @change-count="changeCount"></cart-list>
        <cart-footer :list="list"></cart-footer>
      </div>
    </template>

    <template id="cart-header">
      <div class="title">我的商品</div>
    </template>

    <template id="cart-list">
      <div>
        <div class="item" v-if="list.length === 0" style="text-align: center">暂无数据</div>
        <div class="item" v-for="v in list" :key="v.id">
          <img :src="v.imgSrc" />
          <div class="name">
            <div style="display: flex; flex-direction: column; height: 100%; justify-content: center">
              <div style="line-height: normal">{{ v.title }}</div>
              <div style="line-height: normal">￥{{ v.price }}</div>
            </div>
          </div>
          <div class="change">
            <a href="" @click.prevent="subCount(v)">－</a>
            <input type="text" class="num" :value="v.count" @change="onCountChange(v.id, $event)" />
            <a href="" @click.prevent="addCount(v)">＋</a>
          </div>
          <div class="del" @click="del(v.id)">×</div>
        </div>
      </div>
    </template>

    <template id="cart-footer">
      <div class="total">
        <span>总价：{{ totalMoney }}</span>
        <button>结算</button>
      </div>
    </template>

    <script src="../vue.js"></script>
    <script>
      Vue.component('cart', {
        template: '#cart',
        components: {
          'cart-header': {
            template: '#cart-header',
          },
          'cart-list': {
            template: '#cart-list',
            props: { list: { type: Array, required: true } },
            methods: {
              onCountChange(id, e) {
                const value = parseInt(e.target.value);
                // 下面注释掉的逻辑判断，在父组件监听change-count事件的处理函数中已经处理了
                // 当 value 为 NaN 时， !value  === true
                // if (!value || value < 1) {
                //   // 数量不合法，默认重置为1
                //   e.target.value = 1;
                // } else if (value > 999) {
                //   e.target.value = 999;
                // } else {
                //   // 如果转换成功也要重新设置一下输入框中的值，因为  paserInt('1asfasdf') 得到的是 1
                //   e.target.value = value;
                // }
                this.$emit('change-count', { id, count: value });
              },
              subCount({ id, count }) {
                // this.$emit('sub-count', id);
                // 在现有的数量上减1
                this.$emit('change-count', { id, count: count - 1 });
              },
              addCount({ id, count }) {
                // this.$emit('add-count', id);
                // 在现有的数量上加1
                this.$emit('change-count', { id, count: count + 1 });
              },
              del(id) {
                this.$emit('del', id);
              },
            },
          },
          'cart-footer': {
            template: '#cart-footer',
            props: { list: { type: Array, required: true } },
            computed: {
              totalMoney() {
                let sum = 0;
                this.list.forEach((v) => {
                  sum += v.price * v.count;
                });
                return sum;
              },
            },
          },
        },
        data() {
          return {
            list: [
              { id: 1, imgSrc: 'img/a.jpg', title: 'TCL彩电', count: 1, price: 100 },
              { id: 2, imgSrc: 'img/b.jpg', title: '机顶盒', count: 1, price: 200 },
              { id: 3, imgSrc: 'img/c.jpg', title: '海尔冰箱', count: 1, price: 300 },
              { id: 4, imgSrc: 'img/d.jpg', title: '小米手机', count: 1, price: 400 },
              { id: 5, imgSrc: 'img/e.jpg', title: 'PPTV电视', count: 1, price: 500 },
            ],
          };
        },
        methods: {
          changeCount({ id, count }) {
            // 先从 this.list 数组中，找出该id的商品对象
            // 由于是对象，属于引用数据类型，存在数据中的也是存的内存地址，所以找出来之后拿到的也是内存地址，
            // 所以啊，直接根据这个内存地址，找到对应的内存中存储的对象数据，更新即可
            const goods = this.list.find((v) => v.id === id);
            // 为了重新渲染视图，将个数重置为 0，数据才会有变化
            goods.count = 0;
            // vue内部有个diff算法，当检查到数据没有发生变化时，不会重新渲染视图|模板|HTML
            if (!count || count < 1) {
              goods.count = 1;
            } else if (count > 999) {
              goods.count = 999;
            } else {
              goods.count = count;
            }
          },
          // addCount(id) {
          //   const goods = this.list.find((v) => v.id === id);
          //   if (goods.count < 999) {
          //     goods.count++;
          //   }
          // },
          // subCount(id) {
          //   const goods = this.list.find((v) => v.id === id);
          //   if (goods.count > 1) {
          //     goods.count--;
          //   }
          // },
          del(id) {
            // 变异方法：调用完该方法后，会影响源数组
            //   push\pop\unshift\shift\splice\reverse\sort\
            // 非变异方法：调用完该方法后，不会影响源数组
            //   forEach\map\filter\find\findIndex\includes\some\every\join\concat\reduce
            this.list = this.list.filter((v) => v.id !== id);
          },
        },
      });

      var vm = new Vue({
        el: '#app',
        data: {},
      });
    </script>
  </body>
</html>
